<script lang="ts" setup>
import { ref, computed, onMounted,watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { $t } from '@vben/locales';
import {
   TreeSelect,
  Button,
  Card,
  Divider,
  Input,
  message,
  Select,
  SelectOption,
  Space,
  Tree,

  Image,
  Popconfirm,
  Col,
  Row,
  Modal,
  Checkbox,
  Upload as Uploads
} from 'ant-design-vue';
import Upload from "#/components/Upload";
import { Page } from '@vben/common-ui';
import draggable from 'vuedraggable';
import { CatalogList,deleteCatlog,UpdateName,batchdelete,getCatalogCategory,UpdateSort,UpdateCoverImage,} from '#/api/admin/resources';
import { postCategory, putCategory,  deleteCategory, } from '#/api/portal/category';

import Icon from '#/components/Icons';
import { useVbenForm } from '#/adapter/form';
const router = useRouter();
const routeMeta = router.currentRoute.value.meta;
const routeTitle = routeMeta.title.replace('管理', '');




interface Category {
  id: number;
  name: string;
  parent_id: number;
  children?: Category[];
  _level?: number;
}

interface FileInfo {
  id: string;
  name: string;
  coverImage: string;
  fileUrl: string;
  categoryId: string;
  coverImage:[],
}

const categoryTree = ref<Category[]>([]);
const flatCategories = ref<Category[]>([]);
const currentCategoryId = ref<number | undefined>();
const expandedKeys = ref<number[]>([]);
const currentCategoryName = computed(() => {
  if (!currentCategoryId.value) return '全部文件';
  const hit = flatCategories.value.find((c) => c.id === currentCategoryId.value);
  return hit?.name ?? '全部文件';
});

const fileList = ref<FileInfo[]>([]);
const searchKeyword = ref<string>('');
const filterCategory = ref<number | undefined>();




watch(
  fileList,
  (newVal) => {
    newVal.forEach((record) => {
      watch(
        () => record.coverImage?.[0]?.url,
        async (newUrl, oldUrl) => {
          if (newUrl !== oldUrl) {
            
           const data =  await UpdateCoverImage({
              coverImage: newUrl,
              asset_id: record.coverImage?.[0]?.id,
              id: record.id
            });
             message.success(data.msg);
          }
        },
        { immediate: false }
      );
    });
  },
  { immediate: true }
);


const selectedKeys = ref<number[]>([]);


onMounted(async () => {
  await loadCategories();
 
    // 假设 categoryTree 是你的分类树数组
  if (categoryTree.value.length > 0) {
    selectedKeys.value = [categoryTree.value[0]['children'][0].id]; // 默认选中第一个一级分类
    currentCategoryId.value = categoryTree.value[0]['children'][0].id;
    fetchFileList();
  }
});


async function loadCategories() {
  const response = await getCatalogCategory();

  // 先处理数据，给所有节点标记 hideActions
  markHideActions(response.data);

  // 赋值处理后的数据给响应式变量
  categoryTree.value = response.data;

  console.log(categoryTree.value);
  

  flatCategories.value = flatten(response.data);

  expandedKeys.value = flatCategories.value.filter(i => i._level && i._level <= 2).map(i => i.id); // 默认展开前两级
}


function flatten(list: Category[]): Category[] {
  const res: Category[] = [];
  const dfs = (arr: Category[]) => {
    arr.forEach((item) => {
      res.push(item);
      if (item.children?.length) dfs(item.children);
    });
  };
  dfs(list);
  return res;
}
const originalFileList = ref<FileInfo[]>([]);

async function fetchFileList() {
  const apidata = await CatalogList();
  const data: FileInfo[] = apidata.data;

  originalFileList.value = data.map(item => ({ ...item, editing: false, checked: false })); // 先存原始完整数据

  // 先用全部数据，后面筛选用searchKeyworddata函数
  fileList.value = originalFileList.value.slice();


  // 如果想初始化时就过滤，可以调用一次筛选函数
  searchKeyworddata();
}

function searchKeyworddata() {
  const kw = searchKeyword.value.trim().toLowerCase();
  const catId = currentCategoryId.value || filterCategory.value;
console.log('currentCategoryId.value',currentCategoryId.value)
  if (!kw && !catId) {
    // 没关键词也没分类筛选，显示全部
    fileList.value = originalFileList.value.slice();
    return;
  }

  fileList.value = originalFileList.value.filter(file => {
    const matchName = !kw || file.name.toLowerCase().includes(kw);
    const matchCat = !catId || file.categoryId === String(catId);
    return matchName && matchCat;
  });
}




function handleCategorySelect(keys: any[]) {
  currentCategoryId.value = keys[0];
  fetchFileList();
}

function handleCategoryDrop(info: any) {
  console.log('分类拖拽', info);
}



async function deleteFile(record: FileInfo) {
    const { msg } = await deleteCatlog(record.id); // ❗️这里是你定义的 API，传数组 ID
    message.success(msg || 'error');
    if(msg == 'success'){
            fileList.value = fileList.value.filter((file) => file.id !== record.id);
    }
}


function beforeUploadCheck() {
  if (!currentCategoryId.value || currentCategoryId.value <= 0) {
    message.warning($t('admin.pleaseSelectCategoryFirst'));
    return Upload.LIST_IGNORE; // 阻止上传
  }
  return true;
}


function handleUploadChange(info: any) {
  if (info.file.status === 'done') {
    message.success(`${info.file.name} Upload Success`);
    fetchFileList(); // 重新加载当前分类下的文件
  } else if (info.file.status === 'error') {
    message.error(`${info.file.name} Upload Error`);
  }
}


async function saveFileName(record: FileInfo) {
  if (!record.name.trim()) {
    message.warning($t('admin.filenameRequired'));
    return;
  }

  record.editing = false;
  try {
    await UpdateName(record); // 假设你有这个接口
    message.success($t('admin.filenameUpdated'));
  } catch (e) {
    message.error($t('admin.updateFailed'));
  }
}

const showFormModal = ref(false); // 控制 BaseForm 弹窗

const [BaseForm, formModel] = useVbenForm({
  // 所有表单项共用，可单独在表单内覆盖
  commonConfig: {
    // 所有表单项
    componentProps: {
      class: 'w-full',
    },
  },
  handleSubmit: onSubmit,



  layout: 'horizontal',
  schema: [
    {
        component: 'Input',
        fieldName: 'id',
        componentProps: {
            type: 'hidden',
        },
    },

    {
      component: 'TreeSelect',
      fieldName: 'categories',
      label: `${routeTitle}`+" "+$t('page.common.Category'),
      rules: 'required',
    },
   
 
    {
      
      component: 'Input',
      // 对应组件的参数
      componentProps: {
        placeholder: $t("page.common.Please Enter")
      },
      // 字段名
      fieldName: 'name',
      // 界面显示的label
      label: $t("page.common.Category")+" "+$t("page.common.Title"),
    },
    {
      component: 'Upload',
      defaultValue: '',
      componentProps: {
        placeholder: $t("page.common.Please Enter")
      },
      fieldName: 'thumbnail',
      label: $t("page.common.Thumbnail"),
    },
  ],
  wrapperClass: 'grid-cols-1',
});

async function onSubmit(values: Record<string, any>) {

  // 先准备要提交的数据结构
  const data = {
    name: values.name,            
    parent_id: values.categories,   
    alias: '',                 
    description: '',              
    module_id: 14,  
    id:values.id,           
    more: {
      thumbnail: values.thumbnail,
      list_tpl: '',
      one_tpl: '',
    },
  };

  // 生成 alias 逻辑
  if (/^\d+$/.test(values.name)) {
    // name是纯数字，前面加year-
    data.alias = `year-${values.name}`;
  } else {
    // 否则用name作为alias
    data.alias = values.name;
  }

  // 处理修改或新增
  if (values.id) {
    // 编辑
    const { msg } = await putCategory({ ...data, id: values.id });
    showMsg(msg);
  } else {
    // 新增
    const { msg } = await postCategory(data);
    showMsg(msg);
   
  }
   await loadCategories();
    showFormModal.value=false;
}

// 这个是显示消息函数
function showMsg(msg: string) {
  message.success(msg);
}



const hoveredNode = ref<number | null>(null);

async function handleDelete(record: any) {
  try {
    const data = await deleteCategory(record.id);
    console.log(data.msg);  // 这样才能拿到 msg
    loadCategories();
  } catch (error) {
    console.error('删除失败', error);
  }
}


function handleUpdate(record: any) {
  // 触发编辑弹窗，传递 record
  console.log('编辑节点', record);
  openEditModal(record);
}

function openEditModal(record: any) {
   console.log('record',record)
    formModel.setValues ({
        categories: [record.parent_id],  // 选中分类id数组
        name: record.name,
        id:record.id,
        thumbnail:record.more.thumbnail
        
    });
  showFormModal.value=true
}


//文件批量删除
const allSelected = computed<boolean>(() => fileList.value.length > 0 && fileList.value.every(f => f.checked));
function toggleAll(checked: boolean) {
 
  fileList.value.forEach(f => (f.checked = checked));
}

async function batchDelete() {
 const toDel = fileList.value.filter(f => f.checked);
const toDelIds = toDel.map(f => f.id);
  if (!toDel.length) {
    message.warning($t('admin.pleaseSelectFilesToDelete'));
    return;
  }

  const { msg } = await batchdelete({id:toDelIds});
  
  message.success(msg);
  await fetchFileList();
}



function markHideActions(nodes: any[], parentHasProductLink = false) {
  nodes.forEach(node => {
    // 如果父节点 is_products_link = 1，就强制子节点 hideActions = true
    const currentHasProductLink = parentHasProductLink || node.is_products_link === 1;

    // 自己是否隐藏：如果父链存在产品链接，就隐藏，否则根据自己决定
    node.hideActions = currentHasProductLink && parentHasProductLink;

    if (node.children && node.children.length > 0) {
      // 递归下去，把 "有产品链接" 的状态传递给子节点
      markHideActions(node.children, currentHasProductLink);
    }
  });
}





function filterTreeExcludeProductLink(nodes) {
  return nodes
    .filter(node => node.is_products_link !== 1)
    .map(node => {
      const newNode = { ...node };
      if (newNode.children && newNode.children.length) {
        newNode.children = filterTreeExcludeProductLink(newNode.children);
      }
      return newNode;
    });
}



const filteredCategoryTree = computed(() => {
  return filterTreeExcludeProductLink(categoryTree.value);
});

async function onDragEnd(event) {
    const ids = fileList.value.map(item => item.id);

  await UpdateSort({ids : ids});
}


function openPdf(file) {
  window.open(file, '_blank'); // 替换成你的 PDF 路径
}

function add_category(){

   formModel.setValues({
    id: 0,
    categories: [], // TreeSelect 选中 id 数组
    name: ''
  });



  showFormModal.value = true;

}

</script>

<template>
  <Page>
    <Row :gutter="16">
      <Col :span="8">
        <Card title="分类" size="small">
            <Space class="mb-2">
                <Button size="small" @click="expandedKeys = flatCategories.map(i => i.id)">{{$t('admin.expandAll')}}</Button>
                <Button size="small" @click="expandedKeys = []">{{$t('admin.collapseAll')}}</Button>
            </Space>

          <Tree
                v-model:expandedKeys="expandedKeys"
                v-model:selectedKeys="selectedKeys"  
                :tree-data="categoryTree"
                block-node
                draggable
                :field-names="{ title: 'name', key: 'id', children: 'children' }"
                @drop="handleCategoryDrop"
                @select="handleCategorySelect"
                >
                <template #title="{ data }">
                        <div
                            class="tree-node-title"
                            @mouseenter="hoveredNode = data.id"
                            @mouseleave="hoveredNode = null"
                            style="display: flex; justify-content: space-between; align-items: center; width: 100%;"
                        >
                            <span style="flex: 1;">{{ data.name }}</span>

                            <div v-show="hoveredNode === data.id && !data.hideActions" style="display: flex; gap: 2px; align-items: center;">
                                
                                  <Popconfirm :title="$t('page.common.Confirm Delete')" @confirm="() => handleDelete(data)">
                                    <Button type="link" danger @click.stop>{{$t('page.common.Delete')}}</Button>
                                  </Popconfirm>
                                
                                <a class="update-btn" @click.stop="handleUpdate(data)" >
                                  {{$t('page.common.Edit')}}
                                </a>
                              </div>
                        </div>
                </template>



          </Tree>


                    



          <Button type="primary" block class="mt-2" @click="add_category">
            {{$t('admin.createCategory')}}
          </Button>
        </Card>
        <Modal
            v-model:open="showFormModal"
            :title="$t('page.common.Add')+' '+routeTitle+' '+$t('page.common.Category')"
            :footer="null"
            :style="{ width: '500px' }"
            :centered="true"
            >
            <BaseForm>
            <template #categories="slotProps">
                <TreeSelect
                    v-bind="slotProps"
                    :field-names="{
                        value: 'id',
                        key: 'id',
                        label: 'name',
                        children: 'children',
                    }"
                    :tree-data="filteredCategoryTree"
                    allow-clear
                    :multiple="false"
                    :placeholder="$t('page.common.Please Select')+' '+ $t('page.common.Category')"
                    style="width: 100%"
                    tree-default-expand-all
                    tree-node-filter-prop="label"
                />
                </template>
            </BaseForm>
        </Modal>

      </Col>

      <Col :span="15">
        <Card :title="currentCategoryName" size="small">
            
          <Space class="mb-4" wrap>
           
            <Input
              v-model:value="searchKeyword"
              :placeholder="$t('admin.searchFilename')"
              allow-clear
              @input="searchKeyworddata"
              style="width: 200px"
            />

            <Checkbox :checked="allSelected" @change="e => toggleAll(e.target.checked)">{{$t('admin.selectAll')}}</Checkbox>
            <Popconfirm :title="$t('page.common.Confirm Delete')" @confirm="batchDelete">
                <Button danger size="small" :disabled="!fileList.some(f => f.checked)">{{$t('admin.batchDelete')}}</Button>
            </Popconfirm>
            
       
          </Space>

          <draggable
                :list="fileList"
                item-key="id"
                tag="div"
                class="file-grid"
                 @end="onDragEnd"
                >
                
                <template #item="{ element: record }">
                    <div class="file-card">
                
                    <div class="cover-wrapper" @click="openEditFile(record)">


                        <Upload
                             v-model="record.coverImage"
                            list-type="picture-card"
                            :show-upload-list="{ showPreviewIcon: true, showRemoveIcon: true }"
                            style="width: auto"
                        >
                       
                        </Upload>


                       
                       
                    </div>

                 

                    <template v-if="record.editing">
                        <Input
                            v-model:value="record.name"
                            size="small"
                            style="width: 160px"
                            @blur="() => saveFileName(record)"
                        />
                    </template>
                    <template v-else>
                        <div class="file-name" :title="record.name" @click="record.editing = true" style="cursor: pointer;">
                            {{ record.name==''?'点击编辑':record.name }}
                        </div>
                    </template>

                    <div class="file-actions">
                        <Popconfirm :title="$t('page.common.Confirm Delete')" @confirm="() => deleteFile(record)">
                        <Button type="link" danger style="padding:0">{{$t('page.common.Delete')}}</Button>
                        </Popconfirm>
                         <Button type="link" @click="openPdf(record.fileUrl)">{{$t('admin.View')}}</Button>
                        
                        <Checkbox
                            :checked="record.checked"
                            @change="e => record.checked = e.target.checked"
                            class="mb-1"
                         />

                      
                    </div>
                    </div>
                </template>
          </draggable>



            <Uploads.Dragger
                name="file"
                class="filese"
                :multiple="true"
                :action="'https://static.swm-powersports.com/api/portal/admin/resourcees/upload/Category'"
                :data="{ category_id: currentCategoryId }"
                :before-upload="beforeUploadCheck"
                @change="handleUploadChange"
                >
                <p class="ant-upload-drag-icon">
                    <InboxOutlined />
                </p>
                <p class="ant-upload-text">{{$t('admin.clickOrDragToUpload')}}</p>
                <p class="ant-upload-hint">{{$t('admin.supportSingleOrBatchUpload')}}</p>
                </Uploads.Dragger>

        </Card>
      </Col>
    </Row>
  </Page>
</template>



<style lang="scss" scoped>
.filese {
  :deep(.ant-upload-list-text) {
    max-height: 200px;
    overflow-y: scroll;
  }
}

.mt-2 {
  margin-top: 0.5rem;
}
.file-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 20px;
  margin-bottom: 20px;
  max-height: 70vh;
  overflow-y: scroll;
}

.file-card {
  width: 180px;
  border: 1px solid #f0f0f0;
  border-radius: 6px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.cover-wrapper {
  margin-bottom: 8px;
}

.file-name {
    font-size: 12px;
  text-align: center;
  margin-bottom: 8px;
  /* 允许换行，最多两行 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  /* 兼容性写法 */
  line-clamp: 2;
  box-orient: vertical;
  width: 100%;
  /* 确保换行 */
  white-space: normal;
  word-wrap: break-word;
  word-break: break-all;
}

.file-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
  width: 100%;
}

</style>
